Micron Document
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| SparkN0de-git | SparkN0de |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


Displaying Raw • Download


meshchatx/src/backend/http/routes/rrc.py 32e97c105419d3bcede5c1311df3ffb63b8305a4 (32e97c10) Text, 28.88 KB

T8b949e# SPDX-License-Identifier: 0BSD
T8b949e"""HTTP routes: rrc."""

Tff7b72from T7ee787__future__ Tff7b72import Te6edf3annotations


Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backendT7ee787.T7ee787httpT7ee787.T7ee787meshchat_names Tff7b72import Tb4b4b4( T8b949e# noqa: F401
Te6edf3GeoValidationErrorTb4b4b4,
Te6edf3OutboundHttpBlockedErrorTb4b4b4,
Te6edf3OverlayExportErrorTb4b4b4,
Te6edf3OverlaySourceParseErrorTb4b4b4,
Te6edf3PluginSecurityErrorTb4b4b4,
Te6edf3AsyncUtilsTb4b4b4,
Te6edf3InterfaceConfigParserTb4b4b4,
Te6edf3InterfaceDiscoveryTb4b4b4,
Te6edf3InterfaceEditorTb4b4b4,
Te6edf3LOGIN_PATHTb4b4b4,
Te6edf3LXMFTb4b4b4,
Te6edf3LxmfAudioFieldTb4b4b4,
Te6edf3LxmfFileAttachmentTb4b4b4,
Te6edf3LxmfFileAttachmentsFieldTb4b4b4,
Te6edf3LxmfImageFieldTb4b4b4,
Te6edf3MAX_EXPORT_TILESTb4b4b4,
Te6edf3MarkdownRendererTb4b4b4,
Te6edf3NomadnetFileDownloaderTb4b4b4,
Te6edf3NomadnetPageDownloaderTb4b4b4,
Te6edf3RNProbeHandlerTb4b4b4,
Te6edf3RNSTb4b4b4,
Te6edf3ReticulumMeshChatTb4b4b4,
Te6edf3SETUP_PATHTb4b4b4,
Te6edf3TRANSPARENT_TILETb4b4b4,
Te6edf3TelemeterTb4b4b4,
Te6edf3UTCTb4b4b4,
Te6edf3WSMsgTypeTb4b4b4,
Te6edf3_is_chaquopy_androidTb4b4b4,
Te6edf3_is_loopback_bind_hostTb4b4b4,
Te6edf3_request_client_ipTb4b4b4,
Te6edf3aiohttpTb4b4b4,
Te6edf3app_versionTb4b4b4,
Te6edf3assert_migration_context_pathsTb4b4b4,
Te6edf3asyncioTb4b4b4,
Te6edf3base64Tb4b4b4,
Te6edf3bcryptTb4b4b4,
Te6edf3binasciiTb4b4b4,
Te6edf3build_blocklist_export_documentTb4b4b4,
Te6edf3build_export_documentTb4b4b4,
Te6edf3build_messages_export_bundleTb4b4b4,
Te6edf3cache_statsTb4b4b4,
Te6edf3cancel_inbound_deliveriesTb4b4b4,
Te6edf3castTb4b4b4,
Te6edf3compute_lxmf_conversation_unread_from_latest_rowTb4b4b4,
Te6edf3configparserTb4b4b4,
Te6edf3contextlibTb4b4b4,
Te6edf3convert_db_favourite_to_dictTb4b4b4,
Te6edf3convert_db_lxmf_message_to_dictTb4b4b4,
Te6edf3convert_lxmf_message_to_dictTb4b4b4,
Te6edf3convert_nomadnet_field_data_to_mapTb4b4b4,
Te6edf3convert_nomadnet_string_data_to_mapTb4b4b4,
Te6edf3convert_propagation_node_state_to_stringTb4b4b4,
Te6edf3copyTb4b4b4,
Te6edf3datetimeTb4b4b4,
Te6edf3describe_port_conflictTb4b4b4,
Te6edf3detect_image_format_from_magicTb4b4b4,
Te6edf3ensure_outbound_http_allowedTb4b4b4,
Te6edf3ensure_session_csrf_tokenTb4b4b4,
Te6edf3filter_announced_dicts_by_search_queryTb4b4b4,
Te6edf3fresh_storage_at_targetTb4b4b4,
Te6edf3get_cached_active_linkTb4b4b4,
Te6edf3get_file_pathTb4b4b4,
Te6edf3get_sessionTb4b4b4,
Te6edf3get_trusted_proxy_cidrsTb4b4b4,
Te6edf3gif_utilsTb4b4b4,
Te6edf3i2p_supportTb4b4b4,
Te6edf3import_messages_export_bundleTb4b4b4,
Te6edf3ioTb4b4b4,
Te6edf3is_mbtiles_filenameTb4b4b4,
Te6edf3is_path_within_dirTb4b4b4,
Te6edf3is_port_in_useTb4b4b4,
Te6edf3is_user_facing_lxmf_payloadTb4b4b4,
Te6edf3jsonTb4b4b4,
Te6edf3list_host_network_interfacesTb4b4b4,
Te6edf3list_inbound_deliveriesTb4b4b4,
Te6edf3list_portsTb4b4b4,
Te6edf3load_app_security_settingsTb4b4b4,
Te6edf3loggerTb4b4b4,
Te6edf3loggingTb4b4b4,
Te6edf3lxmf_sidebar_preview_for_conversation_latest_rowTb4b4b4,
Te6edf3memory_log_handlerTb4b4b4,
Te6edf3message_fields_have_attachmentsTb4b4b4,
Te6edf3migrate_legacy_to_targetTb4b4b4,
Te6edf3mime_for_image_typeTb4b4b4,
Te6edf3normalize_identity_storage_hashTb4b4b4,
Te6edf3normalize_lxmf_sieve_filtersTb4b4b4,
Te6edf3normalize_message_blocklistTb4b4b4,
Te6edf3osTb4b4b4,
Te6edf3parse_bool_query_paramTb4b4b4,
Te6edf3parse_import_documentTb4b4b4,
Te6edf3parse_lxmf_display_nameTb4b4b4,
Te6edf3parse_lxmf_propagation_node_app_dataTb4b4b4,
Te6edf3parse_lxmf_sieve_filters_jsonTb4b4b4,
Te6edf3parse_lxmf_stamp_costTb4b4b4,
Te6edf3parse_message_blocklist_jsonTb4b4b4,
Te6edf3parse_nomadnetwork_node_display_nameTb4b4b4,
Te6edf3platformTb4b4b4,
Te6edf3privacy_mode_enabledTb4b4b4,
Te6edf3psutilTb4b4b4,
Te6edf3purge_messages_before_cutoffTb4b4b4,
Te6edf3reTb4b4b4,
Te6edf3resolve_message_age_cutoffTb4b4b4,
Te6edf3reticulum_pathfindingTb4b4b4,
Te6edf3rotate_session_csrf_tokenTb4b4b4,
Te6edf3rrc_protocolTb4b4b4,
Te6edf3safe_path_under_dirTb4b4b4,
Te6edf3sanitize_sticker_emojiTb4b4b4,
Te6edf3sanitize_sticker_nameTb4b4b4,
Te6edf3sanitize_websocket_config_updateTb4b4b4,
Te6edf3save_app_security_settingsTb4b4b4,
Te6edf3secretsTb4b4b4,
Te6edf3shutilTb4b4b4,
Te6edf3sqlite3Tb4b4b4,
Te6edf3sticker_pack_utilsTb4b4b4,
Te6edf3sysTb4b4b4,
Te6edf3tempfileTb4b4b4,
Te6edf3threadingTb4b4b4,
Te6edf3timeTb4b4b4,
Te6edf3tracebackTb4b4b4,
Te6edf3user_agent_hashTb4b4b4,
Te6edf3validate_export_documentTb4b4b4,
Te6edf3webTb4b4b4,
Te6edf3websocket_type_requires_authTb4b4b4,
Te6edf3zipfileTb4b4b4,
Tb4b4b4)


Tff7b72def Td2a8ffregister_rrc_routesTb4b4b4(Te6edf3routesTb4b4b4, Te6edf3appTb4b4b4)Tb4b4b4:

T8b949e# Reticulum Relay Chat
Te6edf3RRC_ROOM_MESSAGES_DEFAULT_LIMIT Tff7b72= T79c0ff200
Te6edf3RRC_ROOM_MESSAGES_MAX_LIMIT Tff7b72= T79c0ff1000

Tff7b72def Td2a8ff_rrc_require_managerTb4b4b4(Tb4b4b4)Tb4b4b4:
Te6edf3manager Tff7b72= Te6edf3appTff7b72.Td2a8ffrrc_manager
Tff7b72if Te6edf3manager Tff7b72is Tff7b72NoneTb4b4b4:
Tff7b72return Tff7b72NoneTb4b4b4, Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(
Tb4b4b4{Ta5d6ff"Ta5d6ffmessageTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffRelay chat is not availableTa5d6ff"Tb4b4b4}Tb4b4b4,
Te6edf3statusTff7b72=T79c0ff503Tb4b4b4,
Tb4b4b4)
Tff7b72return Te6edf3managerTb4b4b4, Tff7b72None

Tff7b72def Td2a8ff_rrc_require_hubTb4b4b4(Te6edf3hub_hash_hexTb4b4b4)Tb4b4b4:
Te6edf3managerTb4b4b4, Te6edf3error Tff7b72= Te6edf3_rrc_require_managerTb4b4b4(Tb4b4b4)
Tff7b72if Te6edf3error Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Tff7b72return Tff7b72NoneTb4b4b4, Tff7b72NoneTb4b4b4, Te6edf3error
Te6edf3hub Tff7b72= Te6edf3managerTff7b72.Td2a8fffind_hub_by_hexTb4b4b4(Te6edf3hub_hash_hexTb4b4b4)
Tff7b72if Te6edf3hub Tff7b72is Tff7b72NoneTb4b4b4:
Tff7b72return Tb4b4b4(
Te6edf3managerTb4b4b4,
Tff7b72NoneTb4b4b4,
Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(
Tb4b4b4{Ta5d6ff"Ta5d6ffmessageTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffHub not foundTa5d6ff"Tb4b4b4}Tb4b4b4,
Te6edf3statusTff7b72=T79c0ff404Tb4b4b4,
Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Tff7b72return Te6edf3managerTb4b4b4, Te6edf3hubTb4b4b4, Tff7b72None

Tf0883e@routesTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/rrc/hubsTa5d6ff"Tb4b4b4)
Tff7b72async Tff7b72def Td2a8ffrrc_hubs_getTb4b4b4(Te6edf3requestTb4b4b4)Tb4b4b4:
Te6edf3managerTb4b4b4, Te6edf3error Tff7b72= Te6edf3_rrc_require_managerTb4b4b4(Tb4b4b4)
Tff7b72if Te6edf3error Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Tff7b72return Te6edf3error
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Te6edf3managerTff7b72.Td2a8ffto_dictTb4b4b4(Tb4b4b4)Tb4b4b4)

Tf0883e@routesTff7b72.Td2a8ffpostTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/rrc/hubsTa5d6ff"Tb4b4b4)
Tff7b72async Tff7b72def Td2a8ffrrc_hubs_postTb4b4b4(Te6edf3requestTb4b4b4)Tb4b4b4:
Te6edf3managerTb4b4b4, Te6edf3error Tff7b72= Te6edf3_rrc_require_managerTb4b4b4(Tb4b4b4)
Tff7b72if Te6edf3error Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Tff7b72return Te6edf3error
Te6edf3data Tff7b72= Tff7b72await Te6edf3requestTff7b72.Td2a8ffjsonTb4b4b4(Tb4b4b4)
Te6edf3hub_hash_hex Tff7b72= Tb4b4b4(Te6edf3dataTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffhub_hashTa5d6ff"Tb4b4b4) Tff7b72or Ta5d6ff"Ta5d6ff"Tb4b4b4)Tff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4)
Tff7b72tryTb4b4b4:
Te6edf3hub_hash Tff7b72= Tffa657bytesTff7b72.Td2a8fffromhexTb4b4b4(Te6edf3hub_hash_hexTb4b4b4)
Tff7b72except Tb4b4b4(Tf85149ValueErrorTb4b4b4, Tf85149TypeErrorTb4b4b4)Tb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(
Tb4b4b4{Ta5d6ff"Ta5d6ffmessageTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffA valid hub hash is requiredTa5d6ff"Tb4b4b4}Tb4b4b4,
Te6edf3statusTff7b72=T79c0ff400Tb4b4b4,
Tb4b4b4)
Tff7b72if Tffa657lenTb4b4b4(Te6edf3hub_hashTb4b4b4) Tff7b72!= Te6edf3rrc_protocolTff7b72.Td2a8ffHUB_HASH_BYTESTb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(
Tb4b4b4{Ta5d6ff"Ta5d6ffmessageTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffHub hash has an invalid lengthTa5d6ff"Tb4b4b4}Tb4b4b4,
Te6edf3statusTff7b72=T79c0ff400Tb4b4b4,
Tb4b4b4)
Te6edf3dest_name Tff7b72= Te6edf3dataTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffdest_nameTa5d6ff"Tb4b4b4) Tff7b72or Tff7b72None
Te6edf3name Tff7b72= Te6edf3dataTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffnameTa5d6ff"Tb4b4b4) Tff7b72or Tff7b72None
Te6edf3hub Tff7b72= Te6edf3managerTff7b72.Td2a8ffadd_hubTb4b4b4(Te6edf3hub_hashTb4b4b4, Te6edf3dest_nameTff7b72=Te6edf3dest_nameTb4b4b4, Te6edf3nameTff7b72=Te6edf3nameTb4b4b4)
Tff7b72if Te6edf3dataTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffconnectTa5d6ff"Tb4b4b4)Tb4b4b4:
Te6edf3hubTff7b72.Td2a8ffconnectTb4b4b4(Tb4b4b4)
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6ffhubTa5d6ff"Tb4b4b4: Te6edf3hubTff7b72.Td2a8ffto_dictTb4b4b4(Tb4b4b4)Tb4b4b4}Tb4b4b4)

Tf0883e@routesTff7b72.Td2a8ffdeleteTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/rrc/hubs/Tffd700{hub_hash}Ta5d6ff"Tb4b4b4)
Tff7b72async Tff7b72def Td2a8ffrrc_hub_deleteTb4b4b4(Te6edf3requestTb4b4b4)Tb4b4b4:
Te6edf3managerTb4b4b4, Te6edf3hubTb4b4b4, Te6edf3error Tff7b72= Te6edf3_rrc_require_hubTb4b4b4(
Te6edf3requestTff7b72.Td2a8ffmatch_infoTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffhub_hashTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ff"Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Tff7b72if Te6edf3error Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Tff7b72return Te6edf3error
Te6edf3managerTff7b72.Td2a8ffremove_hubTb4b4b4(Te6edf3hubTb4b4b4)
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6ffmessageTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffHub removedTa5d6ff"Tb4b4b4}Tb4b4b4)

Tf0883e@routesTff7b72.Td2a8ffpatchTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/rrc/hubs/Tffd700{hub_hash}Ta5d6ff"Tb4b4b4)
Tff7b72async Tff7b72def Td2a8ffrrc_hub_patchTb4b4b4(Te6edf3requestTb4b4b4)Tb4b4b4:
Te6edf3_Tb4b4b4, Te6edf3hubTb4b4b4, Te6edf3error Tff7b72= Te6edf3_rrc_require_hubTb4b4b4(Te6edf3requestTff7b72.Td2a8ffmatch_infoTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffhub_hashTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ff"Tb4b4b4)Tb4b4b4)
Tff7b72if Te6edf3error Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Tff7b72return Te6edf3error
Te6edf3data Tff7b72= Tff7b72await Te6edf3requestTff7b72.Td2a8ffjsonTb4b4b4(Tb4b4b4)
Tff7b72if Ta5d6ff"Ta5d6ffauto_reconnectTa5d6ff" Tff7b72in Te6edf3dataTb4b4b4:
Te6edf3hubTff7b72.Td2a8ffset_auto_reconnectTb4b4b4(Tffa657boolTb4b4b4(Te6edf3dataTb4b4b4[Ta5d6ff"Ta5d6ffauto_reconnectTa5d6ff"Tb4b4b4]Tb4b4b4)Tb4b4b4)
Tff7b72if Ta5d6ff"Ta5d6ffauto_listTa5d6ff" Tff7b72in Te6edf3dataTb4b4b4:
Te6edf3hubTff7b72.Td2a8ffset_auto_listTb4b4b4(Tffa657boolTb4b4b4(Te6edf3dataTb4b4b4[Ta5d6ff"Ta5d6ffauto_listTa5d6ff"Tb4b4b4]Tb4b4b4)Tb4b4b4)
Tff7b72if Ta5d6ff"Ta5d6ffauto_whoTa5d6ff" Tff7b72in Te6edf3dataTb4b4b4:
Te6edf3hubTff7b72.Td2a8ffset_auto_whoTb4b4b4(Tffa657boolTb4b4b4(Te6edf3dataTb4b4b4[Ta5d6ff"Ta5d6ffauto_whoTa5d6ff"Tb4b4b4]Tb4b4b4)Tb4b4b4)
Tff7b72if Ta5d6ff"Ta5d6ffnickTa5d6ff" Tff7b72in Te6edf3dataTb4b4b4:
Te6edf3hubTff7b72.Td2a8ffset_nick_overrideTb4b4b4(Te6edf3dataTb4b4b4[Ta5d6ff"Ta5d6ffnickTa5d6ff"Tb4b4b4]Tb4b4b4)
Tff7b72if Ta5d6ff"Ta5d6ffcustom_nameTa5d6ff" Tff7b72in Te6edf3dataTb4b4b4:
Te6edf3hubTff7b72.Td2a8ffset_custom_nameTb4b4b4(Te6edf3dataTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffcustom_nameTa5d6ff"Tb4b4b4)Tb4b4b4)
Tff7b72if Te6edf3dataTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffrevert_custom_nameTa5d6ff"Tb4b4b4)Tb4b4b4:
Te6edf3hubTff7b72.Td2a8ffset_custom_nameTb4b4b4(Tff7b72NoneTb4b4b4)
Tff7b72if Ta5d6ff"Ta5d6ffhub_iconTa5d6ff" Tff7b72in Te6edf3dataTb4b4b4:
Tff7b72tryTb4b4b4:
Te6edf3hubTff7b72.Td2a8ffset_hub_iconTb4b4b4(Te6edf3dataTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffhub_iconTa5d6ff"Tb4b4b4)Tb4b4b4)
Tff7b72except Tf85149ValueError Tff7b72as Te6edf3eTb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6ffmessageTa5d6ff"Tb4b4b4: Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4}Tb4b4b4, Te6edf3statusTff7b72=T79c0ff400Tb4b4b4)
Tff7b72if Te6edf3dataTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffrevert_hub_iconTa5d6ff"Tb4b4b4)Tb4b4b4:
Te6edf3hubTff7b72.Td2a8ffset_hub_iconTb4b4b4(Tff7b72NoneTb4b4b4)
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6ffhubTa5d6ff"Tb4b4b4: Te6edf3hubTff7b72.Td2a8ffto_dictTb4b4b4(Tb4b4b4)Tb4b4b4}Tb4b4b4)

Tf0883e@routesTff7b72.Td2a8ffputTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/rrc/hubs/orderTa5d6ff"Tb4b4b4)
Tff7b72async Tff7b72def Td2a8ffrrc_hubs_reorderTb4b4b4(Te6edf3requestTb4b4b4)Tb4b4b4:
Te6edf3managerTb4b4b4, Te6edf3error Tff7b72= Te6edf3_rrc_require_managerTb4b4b4(Tb4b4b4)
Tff7b72if Te6edf3error Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Tff7b72return Te6edf3error
Te6edf3data Tff7b72= Tff7b72await Te6edf3requestTff7b72.Td2a8ffjsonTb4b4b4(Tb4b4b4)
Te6edf3hub_hashes Tff7b72= Te6edf3dataTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffhub_hashesTa5d6ff"Tb4b4b4)
Tff7b72if Tff7b72not Tffa657isinstanceTb4b4b4(Te6edf3hub_hashesTb4b4b4, Tffa657listTb4b4b4)Tb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(
Tb4b4b4{Ta5d6ff"Ta5d6ffmessageTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffhub_hashes must be a listTa5d6ff"Tb4b4b4}Tb4b4b4,
Te6edf3statusTff7b72=T79c0ff400Tb4b4b4,
Tb4b4b4)
Tff7b72if Tff7b72not Te6edf3managerTff7b72.Td2a8ffreorder_hubsTb4b4b4(Te6edf3hub_hashesTb4b4b4)Tb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(
Tb4b4b4{Ta5d6ff"Ta5d6ffmessageTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffInvalid hub orderTa5d6ff"Tb4b4b4}Tb4b4b4,
Te6edf3statusTff7b72=T79c0ff400Tb4b4b4,
Tb4b4b4)
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Te6edf3managerTff7b72.Td2a8ffto_dictTb4b4b4(Tb4b4b4)Tb4b4b4)

Tf0883e@routesTff7b72.Td2a8ffputTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/rrc/hubs/Tffd700{hub_hash}Ta5d6ff/rooms/orderTa5d6ff"Tb4b4b4)
Tff7b72async Tff7b72def Td2a8ffrrc_hub_rooms_reorderTb4b4b4(Te6edf3requestTb4b4b4)Tb4b4b4:
Te6edf3_Tb4b4b4, Te6edf3hubTb4b4b4, Te6edf3error Tff7b72= Te6edf3_rrc_require_hubTb4b4b4(Te6edf3requestTff7b72.Td2a8ffmatch_infoTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffhub_hashTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ff"Tb4b4b4)Tb4b4b4)
Tff7b72if Te6edf3error Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Tff7b72return Te6edf3error
Te6edf3data Tff7b72= Tff7b72await Te6edf3requestTff7b72.Td2a8ffjsonTb4b4b4(Tb4b4b4)
Te6edf3room_names Tff7b72= Te6edf3dataTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffroom_namesTa5d6ff"Tb4b4b4)
Tff7b72if Tff7b72not Tffa657isinstanceTb4b4b4(Te6edf3room_namesTb4b4b4, Tffa657listTb4b4b4)Tb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(
Tb4b4b4{Ta5d6ff"Ta5d6ffmessageTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffroom_names must be a listTa5d6ff"Tb4b4b4}Tb4b4b4,
Te6edf3statusTff7b72=T79c0ff400Tb4b4b4,
Tb4b4b4)
Tff7b72if Tff7b72not Te6edf3hubTff7b72.Td2a8ffreorder_roomsTb4b4b4(Te6edf3room_namesTb4b4b4)Tb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(
Tb4b4b4{Ta5d6ff"Ta5d6ffmessageTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffInvalid room orderTa5d6ff"Tb4b4b4}Tb4b4b4,
Te6edf3statusTff7b72=T79c0ff400Tb4b4b4,
Tb4b4b4)
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6ffhubTa5d6ff"Tb4b4b4: Te6edf3hubTff7b72.Td2a8ffto_dictTb4b4b4(Tb4b4b4)Tb4b4b4}Tb4b4b4)

Tf0883e@routesTff7b72.Td2a8ffpostTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/rrc/hubs/Tffd700{hub_hash}Ta5d6ff/rooms/listTa5d6ff"Tb4b4b4)
Tff7b72async Tff7b72def Td2a8ffrrc_hub_rooms_listTb4b4b4(Te6edf3requestTb4b4b4)Tb4b4b4:
Te6edf3_Tb4b4b4, Te6edf3hubTb4b4b4, Te6edf3error Tff7b72= Te6edf3_rrc_require_hubTb4b4b4(Te6edf3requestTff7b72.Td2a8ffmatch_infoTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffhub_hashTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ff"Tb4b4b4)Tb4b4b4)
Tff7b72if Te6edf3error Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Tff7b72return Te6edf3error
Tff7b72tryTb4b4b4:
Te6edf3hubTff7b72.Td2a8ffrequest_room_listTb4b4b4(Tb4b4b4)
Tff7b72except Tb4b4b4(Tf85149ValueErrorTb4b4b4, Tf85149RuntimeErrorTb4b4b4) Tff7b72as Te6edf3eTb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6ffmessageTa5d6ff"Tb4b4b4: Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4}Tb4b4b4, Te6edf3statusTff7b72=T79c0ff400Tb4b4b4)
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(
Tb4b4b4{Ta5d6ff"Ta5d6ffmessageTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffRoom list requestedTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffhubTa5d6ff"Tb4b4b4: Te6edf3hubTff7b72.Td2a8ffto_dictTb4b4b4(Tb4b4b4)Tb4b4b4}
Tb4b4b4)

Tf0883e@routesTff7b72.Td2a8ffpostTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/rrc/hubs/Tffd700{hub_hash}Ta5d6ff/connectTa5d6ff"Tb4b4b4)
Tff7b72async Tff7b72def Td2a8ffrrc_hub_connectTb4b4b4(Te6edf3requestTb4b4b4)Tb4b4b4:
Te6edf3_Tb4b4b4, Te6edf3hubTb4b4b4, Te6edf3error Tff7b72= Te6edf3_rrc_require_hubTb4b4b4(Te6edf3requestTff7b72.Td2a8ffmatch_infoTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffhub_hashTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ff"Tb4b4b4)Tb4b4b4)
Tff7b72if Te6edf3error Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Tff7b72return Te6edf3error
Te6edf3hubTff7b72.Td2a8ffconnectTb4b4b4(Tb4b4b4)
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6ffhubTa5d6ff"Tb4b4b4: Te6edf3hubTff7b72.Td2a8ffto_dictTb4b4b4(Tb4b4b4)Tb4b4b4}Tb4b4b4)

Tf0883e@routesTff7b72.Td2a8ffpostTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/rrc/hubs/Tffd700{hub_hash}Ta5d6ff/disconnectTa5d6ff"Tb4b4b4)
Tff7b72async Tff7b72def Td2a8ffrrc_hub_disconnectTb4b4b4(Te6edf3requestTb4b4b4)Tb4b4b4:
Te6edf3_Tb4b4b4, Te6edf3hubTb4b4b4, Te6edf3error Tff7b72= Te6edf3_rrc_require_hubTb4b4b4(Te6edf3requestTff7b72.Td2a8ffmatch_infoTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffhub_hashTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ff"Tb4b4b4)Tb4b4b4)
Tff7b72if Te6edf3error Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Tff7b72return Te6edf3error
Te6edf3hubTff7b72.Td2a8ffdisconnectTb4b4b4(Tb4b4b4)
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6ffhubTa5d6ff"Tb4b4b4: Te6edf3hubTff7b72.Td2a8ffto_dictTb4b4b4(Tb4b4b4)Tb4b4b4}Tb4b4b4)

Tf0883e@routesTff7b72.Td2a8ffpostTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/rrc/hubs/Tffd700{hub_hash}Ta5d6ff/roomsTa5d6ff"Tb4b4b4)
Tff7b72async Tff7b72def Td2a8ffrrc_hub_join_roomTb4b4b4(Te6edf3requestTb4b4b4)Tb4b4b4:
Te6edf3managerTb4b4b4, Te6edf3hubTb4b4b4, Te6edf3error Tff7b72= Te6edf3_rrc_require_hubTb4b4b4(Te6edf3requestTff7b72.Td2a8ffmatch_infoTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffhub_hashTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ff"Tb4b4b4)Tb4b4b4)
Tff7b72if Te6edf3error Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Tff7b72return Te6edf3error
Te6edf3data Tff7b72= Tff7b72await Te6edf3requestTff7b72.Td2a8ffjsonTb4b4b4(Tb4b4b4)
Te6edf3room Tff7b72= Tb4b4b4(Te6edf3dataTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffroomTa5d6ff"Tb4b4b4) Tff7b72or Ta5d6ff"Ta5d6ff"Tb4b4b4)Tff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4)
Tff7b72if Tff7b72not Te6edf3roomTb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(
Tb4b4b4{Ta5d6ff"Ta5d6ffmessageTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffA room name is requiredTa5d6ff"Tb4b4b4}Tb4b4b4,
Te6edf3statusTff7b72=T79c0ff400Tb4b4b4,
Tb4b4b4)
Te6edf3key Tff7b72= Te6edf3dataTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffkeyTa5d6ff"Tb4b4b4)
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3keyTb4b4b4, Tffa657strTb4b4b4)Tb4b4b4:
Te6edf3key Tff7b72= Te6edf3keyTff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4) Tff7b72or Tff7b72None
Tff7b72elseTb4b4b4:
Te6edf3key Tff7b72= Tff7b72None
Te6edf3remember Tff7b72= Tffa657boolTb4b4b4(Te6edf3dataTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffrememberTa5d6ff"Tb4b4b4, Tff7b72TrueTb4b4b4)Tb4b4b4)
Tff7b72if Te6edf3key Tff7b72is Tff7b72NoneTb4b4b4:
Tff7b72with Te6edf3contextlibTff7b72.Td2a8ffsuppressTb4b4b4(Tf85149ExceptionTb4b4b4)Tb4b4b4:
Te6edf3key Tff7b72= Te6edf3managerTff7b72.Td2a8ffget_room_keyTb4b4b4(Te6edf3hubTb4b4b4, Te6edf3roomTb4b4b4)
Tff7b72tryTb4b4b4:
Tff7b72if Te6edf3hubTff7b72.Td2a8ffstatus Tff7b72== Te6edf3hubTff7b72.Td2a8ffSTATUS_CONNECTEDTb4b4b4:
Te6edf3hubTff7b72.Td2a8ffjoin_roomTb4b4b4(Te6edf3roomTb4b4b4, Te6edf3keyTff7b72=Te6edf3keyTb4b4b4)
Tff7b72elseTb4b4b4:
Te6edf3hubTff7b72.Td2a8ffadd_roomTb4b4b4(Te6edf3roomTb4b4b4)
T8b949e# Persist even while offline so WELCOME auto-rejoin can supply +k.
Tff7b72if Te6edf3key Tff7b72and Te6edf3rememberTb4b4b4:
Tff7b72with Te6edf3contextlibTff7b72.Td2a8ffsuppressTb4b4b4(Tf85149ExceptionTb4b4b4)Tb4b4b4:
Te6edf3managerTff7b72.Td2a8ffremember_room_keyTb4b4b4(Te6edf3hubTb4b4b4, Te6edf3roomTb4b4b4, Te6edf3keyTb4b4b4)
Tff7b72except Tb4b4b4(Tf85149ValueErrorTb4b4b4, Tf85149RuntimeErrorTb4b4b4) Tff7b72as Te6edf3eTb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6ffmessageTa5d6ff"Tb4b4b4: Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4}Tb4b4b4, Te6edf3statusTff7b72=T79c0ff400Tb4b4b4)
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(
Tb4b4b4{
Ta5d6ff"Ta5d6ffhubTa5d6ff"Tb4b4b4: Te6edf3hubTff7b72.Td2a8ffto_dictTb4b4b4(Tb4b4b4)Tb4b4b4,
Ta5d6ff"Ta5d6ffhas_stored_keyTa5d6ff"Tb4b4b4: Te6edf3managerTff7b72.Td2a8ffhas_stored_room_keyTb4b4b4(Te6edf3hubTb4b4b4, Te6edf3roomTb4b4b4)Tb4b4b4,
Tb4b4b4}Tb4b4b4,
Tb4b4b4)

Tf0883e@routesTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/rrc/hubs/Tffd700{hub_hash}Ta5d6ff/room-keysTa5d6ff"Tb4b4b4)
Tff7b72async Tff7b72def Td2a8ffrrc_hub_list_room_keysTb4b4b4(Te6edf3requestTb4b4b4)Tb4b4b4:
Te6edf3managerTb4b4b4, Te6edf3hubTb4b4b4, Te6edf3error Tff7b72= Te6edf3_rrc_require_hubTb4b4b4(Te6edf3requestTff7b72.Td2a8ffmatch_infoTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffhub_hashTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ff"Tb4b4b4)Tb4b4b4)
Tff7b72if Te6edf3error Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Tff7b72return Te6edf3error
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6ffkeysTa5d6ff"Tb4b4b4: Te6edf3managerTff7b72.Td2a8fflist_stored_room_keysTb4b4b4(Te6edf3hubTb4b4b4)Tb4b4b4}Tb4b4b4)

Tf0883e@routesTff7b72.Td2a8ffputTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/rrc/hubs/Tffd700{hub_hash}Ta5d6ff/rooms/Tffd700{room}Ta5d6ff/keyTa5d6ff"Tb4b4b4)
Tff7b72async Tff7b72def Td2a8ffrrc_hub_store_room_keyTb4b4b4(Te6edf3requestTb4b4b4)Tb4b4b4:
Te6edf3managerTb4b4b4, Te6edf3hubTb4b4b4, Te6edf3error Tff7b72= Te6edf3_rrc_require_hubTb4b4b4(Te6edf3requestTff7b72.Td2a8ffmatch_infoTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffhub_hashTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ff"Tb4b4b4)Tb4b4b4)
Tff7b72if Te6edf3error Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Tff7b72return Te6edf3error
Te6edf3room Tff7b72= Te6edf3requestTff7b72.Td2a8ffmatch_infoTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffroomTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ff"Tb4b4b4)
Te6edf3data Tff7b72= Tff7b72await Te6edf3requestTff7b72.Td2a8ffjsonTb4b4b4(Tb4b4b4)
Te6edf3key Tff7b72= Te6edf3dataTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffkeyTa5d6ff"Tb4b4b4)
Tff7b72if Tff7b72not Tffa657isinstanceTb4b4b4(Te6edf3keyTb4b4b4, Tffa657strTb4b4b4) Tff7b72or Tff7b72not Te6edf3keyTff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(
Tb4b4b4{Ta5d6ff"Ta5d6ffmessageTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffA room key is requiredTa5d6ff"Tb4b4b4}Tb4b4b4,
Te6edf3statusTff7b72=T79c0ff400Tb4b4b4,
Tb4b4b4)
Tff7b72tryTb4b4b4:
Te6edf3managerTff7b72.Td2a8ffremember_room_keyTb4b4b4(Te6edf3hubTb4b4b4, Te6edf3roomTb4b4b4, Te6edf3keyTff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4)Tb4b4b4)
Tff7b72except Tb4b4b4(Tf85149TypeErrorTb4b4b4, Tf85149ValueErrorTb4b4b4, Tf85149RuntimeErrorTb4b4b4) Tff7b72as Te6edf3eTb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6ffmessageTa5d6ff"Tb4b4b4: Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4}Tb4b4b4, Te6edf3statusTff7b72=T79c0ff400Tb4b4b4)
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(
Tb4b4b4{
Ta5d6ff"Ta5d6ffmessageTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffRoom key savedTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffhas_stored_keyTa5d6ff"Tb4b4b4: Tff7b72TrueTb4b4b4,
Tb4b4b4}Tb4b4b4,
Tb4b4b4)

Tf0883e@routesTff7b72.Td2a8ffdeleteTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/rrc/hubs/Tffd700{hub_hash}Ta5d6ff/rooms/Tffd700{room}Ta5d6ff/keyTa5d6ff"Tb4b4b4)
Tff7b72async Tff7b72def Td2a8ffrrc_hub_delete_room_keyTb4b4b4(Te6edf3requestTb4b4b4)Tb4b4b4:
Te6edf3managerTb4b4b4, Te6edf3hubTb4b4b4, Te6edf3error Tff7b72= Te6edf3_rrc_require_hubTb4b4b4(Te6edf3requestTff7b72.Td2a8ffmatch_infoTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffhub_hashTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ff"Tb4b4b4)Tb4b4b4)
Tff7b72if Te6edf3error Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Tff7b72return Te6edf3error
Te6edf3room Tff7b72= Te6edf3requestTff7b72.Td2a8ffmatch_infoTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffroomTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ff"Tb4b4b4)
Tff7b72tryTb4b4b4:
Te6edf3deleted Tff7b72= Te6edf3managerTff7b72.Td2a8ffforget_room_keyTb4b4b4(Te6edf3hubTb4b4b4, Te6edf3roomTb4b4b4)
Tff7b72except Tf85149ValueError Tff7b72as Te6edf3eTb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6ffmessageTa5d6ff"Tb4b4b4: Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4}Tb4b4b4, Te6edf3statusTff7b72=T79c0ff400Tb4b4b4)
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(
Tb4b4b4{
Ta5d6ff"Ta5d6ffmessageTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffRoom key removedTa5d6ff" Tff7b72if Te6edf3deleted Tff7b72else Ta5d6ff"Ta5d6ffNo stored room keyTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffdeletedTa5d6ff"Tb4b4b4: Tffa657intTb4b4b4(Te6edf3deleted Tff7b72or T79c0ff0Tb4b4b4)Tb4b4b4,
Tb4b4b4}Tb4b4b4,
Tb4b4b4)

Tf0883e@routesTff7b72.Td2a8ffdeleteTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/rrc/hubs/Tffd700{hub_hash}Ta5d6ff/rooms/Tffd700{room}Ta5d6ff"Tb4b4b4)
Tff7b72async Tff7b72def Td2a8ffrrc_hub_part_roomTb4b4b4(Te6edf3requestTb4b4b4)Tb4b4b4:
Te6edf3_Tb4b4b4, Te6edf3hubTb4b4b4, Te6edf3error Tff7b72= Te6edf3_rrc_require_hubTb4b4b4(Te6edf3requestTff7b72.Td2a8ffmatch_infoTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffhub_hashTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ff"Tb4b4b4)Tb4b4b4)
Tff7b72if Te6edf3error Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Tff7b72return Te6edf3error
Te6edf3room Tff7b72= Te6edf3requestTff7b72.Td2a8ffmatch_infoTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffroomTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ff"Tb4b4b4)
Tff7b72tryTb4b4b4:
Tff7b72if Te6edf3hubTff7b72.Td2a8ffstatus Tff7b72== Te6edf3hubTff7b72.Td2a8ffSTATUS_CONNECTEDTb4b4b4:
Te6edf3hubTff7b72.Td2a8ffpart_roomTb4b4b4(Te6edf3roomTb4b4b4)
Tff7b72elseTb4b4b4:
Te6edf3hubTff7b72.Td2a8ffremove_roomTb4b4b4(Te6edf3roomTb4b4b4)
Tff7b72except Tf85149ValueError Tff7b72as Te6edf3eTb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6ffmessageTa5d6ff"Tb4b4b4: Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4}Tb4b4b4, Te6edf3statusTff7b72=T79c0ff400Tb4b4b4)
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6ffhubTa5d6ff"Tb4b4b4: Te6edf3hubTff7b72.Td2a8ffto_dictTb4b4b4(Tb4b4b4)Tb4b4b4}Tb4b4b4)

Tf0883e@routesTff7b72.Td2a8ffdeleteTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/rrc/hubs/Tffd700{hub_hash}Ta5d6ff/rooms/Tffd700{room}Ta5d6ff/messagesTa5d6ff"Tb4b4b4)
Tff7b72async Tff7b72def Td2a8ffrrc_hub_clear_roomTb4b4b4(Te6edf3requestTb4b4b4)Tb4b4b4:
Te6edf3_Tb4b4b4, Te6edf3hubTb4b4b4, Te6edf3error Tff7b72= Te6edf3_rrc_require_hubTb4b4b4(Te6edf3requestTff7b72.Td2a8ffmatch_infoTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffhub_hashTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ff"Tb4b4b4)Tb4b4b4)
Tff7b72if Te6edf3error Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Tff7b72return Te6edf3error
Tff7b72tryTb4b4b4:
Te6edf3hubTff7b72.Td2a8ffclear_messagesTb4b4b4(Te6edf3requestTff7b72.Td2a8ffmatch_infoTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffroomTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ff"Tb4b4b4)Tb4b4b4)
Tff7b72except Tf85149ValueError Tff7b72as Te6edf3eTb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6ffmessageTa5d6ff"Tb4b4b4: Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4}Tb4b4b4, Te6edf3statusTff7b72=T79c0ff400Tb4b4b4)
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6ffmessageTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffMessages clearedTa5d6ff"Tb4b4b4}Tb4b4b4)

Tf0883e@routesTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/rrc/hubs/Tffd700{hub_hash}Ta5d6ff/rooms/Tffd700{room}Ta5d6ff/messagesTa5d6ff"Tb4b4b4)
Tff7b72async Tff7b72def Td2a8ffrrc_hub_room_messagesTb4b4b4(Te6edf3requestTb4b4b4)Tb4b4b4:
Te6edf3managerTb4b4b4, Te6edf3hubTb4b4b4, Te6edf3error Tff7b72= Te6edf3_rrc_require_hubTb4b4b4(
Te6edf3requestTff7b72.Td2a8ffmatch_infoTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffhub_hashTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ff"Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Tff7b72if Te6edf3error Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Tff7b72return Te6edf3error
Te6edf3room Tff7b72= Te6edf3requestTff7b72.Td2a8ffmatch_infoTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffroomTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ff"Tb4b4b4)
Tff7b72tryTb4b4b4:
Te6edf3limit Tff7b72= Tffa657intTb4b4b4(Te6edf3requestTff7b72.Td2a8ffqueryTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6fflimitTa5d6ff"Tb4b4b4, Te6edf3RRC_ROOM_MESSAGES_DEFAULT_LIMITTb4b4b4)Tb4b4b4)
Tff7b72except Tb4b4b4(Tf85149TypeErrorTb4b4b4, Tf85149ValueErrorTb4b4b4)Tb4b4b4:
Te6edf3limit Tff7b72= Te6edf3RRC_ROOM_MESSAGES_DEFAULT_LIMIT
Te6edf3limit Tff7b72= Tffa657maxTb4b4b4(T79c0ff1Tb4b4b4, Tffa657minTb4b4b4(Te6edf3limitTb4b4b4, Te6edf3RRC_ROOM_MESSAGES_MAX_LIMITTb4b4b4)Tb4b4b4)
Te6edf3before_seq_raw Tff7b72= Te6edf3requestTff7b72.Td2a8ffqueryTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffbefore_seqTa5d6ff"Tb4b4b4)
Te6edf3before_seq Tff7b72= Tff7b72None
Tff7b72if Te6edf3before_seq_raw Tff7b72not Tff7b72in Tb4b4b4(Tff7b72NoneTb4b4b4, Ta5d6ff"Ta5d6ff"Tb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
Te6edf3before_seq Tff7b72= Tffa657intTb4b4b4(Te6edf3before_seq_rawTb4b4b4)
Tff7b72except Tb4b4b4(Tf85149TypeErrorTb4b4b4, Tf85149ValueErrorTb4b4b4)Tb4b4b4:
Te6edf3before_seq Tff7b72= Tff7b72None
Tff7b72tryTb4b4b4:
Te6edf3messagesTb4b4b4, Te6edf3has_more Tff7b72= Te6edf3hubTff7b72.Td2a8ffroom_messagesTb4b4b4(
Te6edf3roomTb4b4b4,
Te6edf3limitTff7b72=Te6edf3limitTb4b4b4,
Te6edf3before_seqTff7b72=Te6edf3before_seqTb4b4b4,
Tb4b4b4)
Te6edf3members Tff7b72= Te6edf3hubTff7b72.Td2a8ffmembers_dictTb4b4b4(Te6edf3roomTb4b4b4)
Tff7b72except Tf85149ValueError Tff7b72as Te6edf3eTb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6ffmessageTa5d6ff"Tb4b4b4: Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4}Tb4b4b4, Te6edf3statusTff7b72=T79c0ff400Tb4b4b4)
Te6edf3managerTff7b72.Td2a8ffset_activeTb4b4b4(Te6edf3hubTb4b4b4, Te6edf3roomTb4b4b4)
Te6edf3appTff7b72.Td2a8ff_mark_rrc_mention_notifications_viewedTb4b4b4(
Te6edf3requestTff7b72.Td2a8ffmatch_infoTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffhub_hashTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ff"Tb4b4b4)Tb4b4b4,
Te6edf3roomTb4b4b4,
Tb4b4b4)
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(
Tb4b4b4{Ta5d6ff"Ta5d6ffmessagesTa5d6ff"Tb4b4b4: Te6edf3messagesTb4b4b4, Ta5d6ff"Ta5d6ffmembersTa5d6ff"Tb4b4b4: Te6edf3membersTb4b4b4, Ta5d6ff"Ta5d6ffhas_moreTa5d6ff"Tb4b4b4: Te6edf3has_moreTb4b4b4}Tb4b4b4,
Tb4b4b4)

Tf0883e@routesTff7b72.Td2a8ffpostTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/rrc/hubs/Tffd700{hub_hash}Ta5d6ff/rooms/Tffd700{room}Ta5d6ff/messagesTa5d6ff"Tb4b4b4)
Tff7b72async Tff7b72def Td2a8ffrrc_hub_send_messageTb4b4b4(Te6edf3requestTb4b4b4)Tb4b4b4:
Te6edf3_Tb4b4b4, Te6edf3hubTb4b4b4, Te6edf3error Tff7b72= Te6edf3_rrc_require_hubTb4b4b4(Te6edf3requestTff7b72.Td2a8ffmatch_infoTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffhub_hashTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ff"Tb4b4b4)Tb4b4b4)
Tff7b72if Te6edf3error Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Tff7b72return Te6edf3error
Te6edf3room Tff7b72= Te6edf3requestTff7b72.Td2a8ffmatch_infoTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffroomTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ff"Tb4b4b4)
Te6edf3data Tff7b72= Tff7b72await Te6edf3requestTff7b72.Td2a8ffjsonTb4b4b4(Tb4b4b4)
Te6edf3text Tff7b72= Te6edf3dataTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6fftextTa5d6ff"Tb4b4b4)
Te6edf3is_action Tff7b72= Tffa657boolTb4b4b4(Te6edf3dataTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffactionTa5d6ff"Tb4b4b4)Tb4b4b4)
Tff7b72tryTb4b4b4:
Tff7b72if Te6edf3is_actionTb4b4b4:
Te6edf3hubTff7b72.Td2a8ffsend_actionTb4b4b4(Te6edf3roomTb4b4b4, Te6edf3textTb4b4b4)
Tff7b72elif Tffa657isinstanceTb4b4b4(Te6edf3textTb4b4b4, Tffa657strTb4b4b4) Tff7b72and Te6edf3textTff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4)Tff7b72.Td2a8ffstartswithTb4b4b4(Ta5d6ff"Ta5d6ff/Ta5d6ff"Tb4b4b4)Tb4b4b4:
Te6edf3hubTff7b72.Td2a8ffsend_commandTb4b4b4(Te6edf3textTff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3roomTff7b72=Te6edf3roomTb4b4b4)
Tff7b72elseTb4b4b4:
Te6edf3hubTff7b72.Td2a8ffsend_messageTb4b4b4(Te6edf3roomTb4b4b4, Te6edf3textTb4b4b4)
Tff7b72except Tb4b4b4(Tf85149ValueErrorTb4b4b4, Tf85149RuntimeErrorTb4b4b4) Tff7b72as Te6edf3eTb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6ffmessageTa5d6ff"Tb4b4b4: Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4}Tb4b4b4, Te6edf3statusTff7b72=T79c0ff400Tb4b4b4)
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6ffmessageTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffSentTa5d6ff"Tb4b4b4}Tb4b4b4)

Tf0883e@routesTff7b72.Td2a8ffpostTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/rrc/hubs/Tffd700{hub_hash}Ta5d6ff/rooms/Tffd700{room}Ta5d6ff/readTa5d6ff"Tb4b4b4)
Tff7b72async Tff7b72def Td2a8ffrrc_hub_mark_readTb4b4b4(Te6edf3requestTb4b4b4)Tb4b4b4:
Te6edf3managerTb4b4b4, Te6edf3hubTb4b4b4, Te6edf3error Tff7b72= Te6edf3_rrc_require_hubTb4b4b4(
Te6edf3requestTff7b72.Td2a8ffmatch_infoTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffhub_hashTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ff"Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Tff7b72if Te6edf3error Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Tff7b72return Te6edf3error
Te6edf3room Tff7b72= Te6edf3requestTff7b72.Td2a8ffmatch_infoTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffroomTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ff"Tb4b4b4)
Tff7b72tryTb4b4b4:
Te6edf3managerTff7b72.Td2a8ffset_activeTb4b4b4(Te6edf3hubTb4b4b4, Te6edf3roomTb4b4b4)
Tff7b72except Tf85149ValueError Tff7b72as Te6edf3eTb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6ffmessageTa5d6ff"Tb4b4b4: Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4}Tb4b4b4, Te6edf3statusTff7b72=T79c0ff400Tb4b4b4)
Te6edf3appTff7b72.Td2a8ff_mark_rrc_mention_notifications_viewedTb4b4b4(
Te6edf3requestTff7b72.Td2a8ffmatch_infoTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffhub_hashTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ff"Tb4b4b4)Tb4b4b4,
Te6edf3roomTb4b4b4,
Tb4b4b4)
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6ffmessageTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffMarked readTa5d6ff"Tb4b4b4}Tb4b4b4)

Tf0883e@routesTff7b72.Td2a8ffpostTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/rrc/active/clearTa5d6ff"Tb4b4b4)
Tff7b72async Tff7b72def Td2a8ffrrc_clear_activeTb4b4b4(Te6edf3requestTb4b4b4)Tb4b4b4:
Te6edf3manager Tff7b72= Te6edf3appTff7b72.Td2a8ffrrc_manager
Tff7b72if Te6edf3manager Tff7b72is Tff7b72NoneTb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(
Tb4b4b4{Ta5d6ff"Ta5d6ffmessageTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffRelay chat is not availableTa5d6ff"Tb4b4b4}Tb4b4b4,
Te6edf3statusTff7b72=T79c0ff503Tb4b4b4,
Tb4b4b4)
Te6edf3managerTff7b72.Td2a8ffset_activeTb4b4b4(Tff7b72NoneTb4b4b4, Tff7b72NoneTb4b4b4)
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6ffmessageTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffActive room clearedTa5d6ff"Tb4b4b4}Tb4b4b4)

Tf0883e@routesTff7b72.Td2a8ffpostTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/rrc/hubs/Tffd700{hub_hash}Ta5d6ff/commandTa5d6ff"Tb4b4b4)
Tff7b72async Tff7b72def Td2a8ffrrc_hub_commandTb4b4b4(Te6edf3requestTb4b4b4)Tb4b4b4:
Te6edf3_Tb4b4b4, Te6edf3hubTb4b4b4, Te6edf3error Tff7b72= Te6edf3_rrc_require_hubTb4b4b4(Te6edf3requestTff7b72.Td2a8ffmatch_infoTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffhub_hashTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ff"Tb4b4b4)Tb4b4b4)
Tff7b72if Te6edf3error Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Tff7b72return Te6edf3error
Te6edf3data Tff7b72= Tff7b72await Te6edf3requestTff7b72.Td2a8ffjsonTb4b4b4(Tb4b4b4)
Te6edf3text Tff7b72= Te6edf3dataTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6fftextTa5d6ff"Tb4b4b4)
Te6edf3room Tff7b72= Te6edf3dataTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffroomTa5d6ff"Tb4b4b4) Tff7b72or Tff7b72None
Tff7b72tryTb4b4b4:
Te6edf3hubTff7b72.Td2a8ffsend_commandTb4b4b4(Te6edf3textTb4b4b4, Te6edf3roomTff7b72=Te6edf3roomTb4b4b4)
Tff7b72except Tb4b4b4(Tf85149ValueErrorTb4b4b4, Tf85149RuntimeErrorTb4b4b4) Tff7b72as Te6edf3eTb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6ffmessageTa5d6ff"Tb4b4b4: Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4}Tb4b4b4, Te6edf3statusTff7b72=T79c0ff400Tb4b4b4)
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6ffmessageTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffSentTa5d6ff"Tb4b4b4}Tb4b4b4)

T8b949e# Reticulum Relay Chat hosting (local hubs)
Tff7b72def Td2a8ff_rrc_server_require_managerTb4b4b4(Tb4b4b4)Tb4b4b4:
Te6edf3manager Tff7b72= Te6edf3appTff7b72.Td2a8ffrrc_server_manager
Tff7b72if Te6edf3manager Tff7b72is Tff7b72NoneTb4b4b4:
Tff7b72return Tff7b72NoneTb4b4b4, Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(
Tb4b4b4{Ta5d6ff"Ta5d6ffmessageTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffRelay chat hosting is not availableTa5d6ff"Tb4b4b4}Tb4b4b4,
Te6edf3statusTff7b72=T79c0ff503Tb4b4b4,
Tb4b4b4)
Tff7b72return Te6edf3managerTb4b4b4, Tff7b72None

Tff7b72def Td2a8ff_rrc_server_require_hubTb4b4b4(Te6edf3hub_idTb4b4b4)Tb4b4b4:
Te6edf3managerTb4b4b4, Te6edf3error Tff7b72= Te6edf3_rrc_server_require_managerTb4b4b4(Tb4b4b4)
Tff7b72if Te6edf3error Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Tff7b72return Tff7b72NoneTb4b4b4, Tff7b72NoneTb4b4b4, Te6edf3error
Te6edf3hub Tff7b72= Te6edf3managerTff7b72.Td2a8fffind_hubTb4b4b4(Te6edf3hub_idTb4b4b4)
Tff7b72if Te6edf3hub Tff7b72is Tff7b72NoneTb4b4b4:
Tff7b72return Tb4b4b4(
Te6edf3managerTb4b4b4,
Tff7b72NoneTb4b4b4,
Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(
Tb4b4b4{Ta5d6ff"Ta5d6ffmessageTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffHub not foundTa5d6ff"Tb4b4b4}Tb4b4b4,
Te6edf3statusTff7b72=T79c0ff404Tb4b4b4,
Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Tff7b72return Te6edf3managerTb4b4b4, Te6edf3hubTb4b4b4, Tff7b72None

T8b949e# Reticulum Relay Chat hosting (local hubs)

Tf0883e@routesTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/rrc/serversTa5d6ff"Tb4b4b4)
Tff7b72async Tff7b72def Td2a8ffrrc_servers_getTb4b4b4(Te6edf3requestTb4b4b4)Tb4b4b4:
Te6edf3managerTb4b4b4, Te6edf3error Tff7b72= Te6edf3_rrc_server_require_managerTb4b4b4(Tb4b4b4)
Tff7b72if Te6edf3error Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Tff7b72return Te6edf3error
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Te6edf3managerTff7b72.Td2a8ffto_dictTb4b4b4(Tb4b4b4)Tb4b4b4)

Tf0883e@routesTff7b72.Td2a8ffpostTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/rrc/serversTa5d6ff"Tb4b4b4)
Tff7b72async Tff7b72def Td2a8ffrrc_servers_postTb4b4b4(Te6edf3requestTb4b4b4)Tb4b4b4:
Te6edf3managerTb4b4b4, Te6edf3error Tff7b72= Te6edf3_rrc_server_require_managerTb4b4b4(Tb4b4b4)
Tff7b72if Te6edf3error Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Tff7b72return Te6edf3error
Te6edf3data Tff7b72= Tff7b72await Te6edf3requestTff7b72.Td2a8ffjsonTb4b4b4(Tb4b4b4)
Te6edf3name Tff7b72= Tb4b4b4(Te6edf3dataTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffnameTa5d6ff"Tb4b4b4) Tff7b72or Ta5d6ff"Ta5d6ff"Tb4b4b4)Tff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4) Tff7b72or Tff7b72None
Te6edf3greeting Tff7b72= Tb4b4b4(Te6edf3dataTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffgreetingTa5d6ff"Tb4b4b4) Tff7b72or Ta5d6ff"Ta5d6ff"Tb4b4b4)Tff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4) Tff7b72or Tff7b72None
Te6edf3announce Tff7b72= Tffa657boolTb4b4b4(Te6edf3dataTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffannounceTa5d6ff"Tb4b4b4, Tff7b72TrueTb4b4b4)Tb4b4b4)
Te6edf3enabled Tff7b72= Tffa657boolTb4b4b4(Te6edf3dataTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffenabledTa5d6ff"Tb4b4b4, Tff7b72TrueTb4b4b4)Tb4b4b4)
Te6edf3create_kwargs Tff7b72= Tb4b4b4{
Ta5d6ff"Ta5d6ffnameTa5d6ff"Tb4b4b4: Te6edf3nameTb4b4b4,
Ta5d6ff"Ta5d6ffgreetingTa5d6ff"Tb4b4b4: Te6edf3greetingTb4b4b4,
Ta5d6ff"Ta5d6ffannounceTa5d6ff"Tb4b4b4: Te6edf3announceTb4b4b4,
Ta5d6ff"Ta5d6ffenabledTa5d6ff"Tb4b4b4: Te6edf3enabledTb4b4b4,
Tb4b4b4}
Tff7b72if Ta5d6ff"Ta5d6ffannounce_interval_secondsTa5d6ff" Tff7b72in Te6edf3dataTb4b4b4:
Te6edf3create_kwargsTb4b4b4[Ta5d6ff"Ta5d6ffannounce_interval_secondsTa5d6ff"Tb4b4b4] Tff7b72= Te6edf3dataTff7b72.Td2a8ffgetTb4b4b4(
Ta5d6ff"Ta5d6ffannounce_interval_secondsTa5d6ff"Tb4b4b4,
Tb4b4b4)
Te6edf3hub Tff7b72= Te6edf3managerTff7b72.Td2a8ffcreate_hubTb4b4b4(Tff7b72*Tff7b72*Te6edf3create_kwargsTb4b4b4)
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6ffhubTa5d6ff"Tb4b4b4: Te6edf3hubTff7b72.Td2a8ffto_dictTb4b4b4(Tb4b4b4)Tb4b4b4}Tb4b4b4)

Tf0883e@routesTff7b72.Td2a8ffdeleteTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/rrc/servers/Tffd700{hub_id}Ta5d6ff"Tb4b4b4)
Tff7b72async Tff7b72def Td2a8ffrrc_server_deleteTb4b4b4(Te6edf3requestTb4b4b4)Tb4b4b4:
Te6edf3managerTb4b4b4, Te6edf3_Tb4b4b4, Te6edf3error Tff7b72= Te6edf3_rrc_server_require_hubTb4b4b4(
Te6edf3requestTff7b72.Td2a8ffmatch_infoTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffhub_idTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ff"Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Tff7b72if Te6edf3error Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Tff7b72return Te6edf3error
Te6edf3managerTff7b72.Td2a8ffdelete_hubTb4b4b4(Te6edf3requestTff7b72.Td2a8ffmatch_infoTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffhub_idTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ff"Tb4b4b4)Tb4b4b4)
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6ffmessageTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffHub removedTa5d6ff"Tb4b4b4}Tb4b4b4)

Tf0883e@routesTff7b72.Td2a8ffpatchTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/rrc/servers/Tffd700{hub_id}Ta5d6ff"Tb4b4b4)
Tff7b72async Tff7b72def Td2a8ffrrc_server_patchTb4b4b4(Te6edf3requestTb4b4b4)Tb4b4b4:
Te6edf3managerTb4b4b4, Te6edf3hubTb4b4b4, Te6edf3error Tff7b72= Te6edf3_rrc_server_require_hubTb4b4b4(
Te6edf3requestTff7b72.Td2a8ffmatch_infoTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffhub_idTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ff"Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Tff7b72if Te6edf3error Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Tff7b72return Te6edf3error
Te6edf3data Tff7b72= Tff7b72await Te6edf3requestTff7b72.Td2a8ffjsonTb4b4b4(Tb4b4b4)
Te6edf3managerTff7b72.Td2a8ffupdate_hubTb4b4b4(
Te6edf3hubTff7b72.Td2a8ffhub_idTb4b4b4,
Te6edf3nameTff7b72=Tb4b4b4(Te6edf3dataTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffnameTa5d6ff"Tb4b4b4) Tff7b72if Ta5d6ff"Ta5d6ffnameTa5d6ff" Tff7b72in Te6edf3data Tff7b72else Tff7b72NoneTb4b4b4)Tb4b4b4,
Te6edf3greetingTff7b72=Tb4b4b4(Te6edf3dataTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffgreetingTa5d6ff"Tb4b4b4) Tff7b72if Ta5d6ff"Ta5d6ffgreetingTa5d6ff" Tff7b72in Te6edf3data Tff7b72else Tff7b72NoneTb4b4b4)Tb4b4b4,
Te6edf3announceTff7b72=Tb4b4b4(Te6edf3dataTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffannounceTa5d6ff"Tb4b4b4) Tff7b72if Ta5d6ff"Ta5d6ffannounceTa5d6ff" Tff7b72in Te6edf3data Tff7b72else Tff7b72NoneTb4b4b4)Tb4b4b4,
Te6edf3announce_interval_secondsTff7b72=Tb4b4b4(
Te6edf3dataTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffannounce_interval_secondsTa5d6ff"Tb4b4b4)
Tff7b72if Ta5d6ff"Ta5d6ffannounce_interval_secondsTa5d6ff" Tff7b72in Te6edf3data
Tff7b72else Tff7b72None
Tb4b4b4)Tb4b4b4,
Te6edf3trusted_identitiesTff7b72=Tb4b4b4(
Te6edf3dataTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6fftrusted_identitiesTa5d6ff"Tb4b4b4) Tff7b72if Ta5d6ff"Ta5d6fftrusted_identitiesTa5d6ff" Tff7b72in Te6edf3data Tff7b72else Tff7b72None
Tb4b4b4)Tb4b4b4,
Te6edf3banned_identitiesTff7b72=Tb4b4b4(
Te6edf3dataTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffbanned_identitiesTa5d6ff"Tb4b4b4) Tff7b72if Ta5d6ff"Ta5d6ffbanned_identitiesTa5d6ff" Tff7b72in Te6edf3data Tff7b72else Tff7b72None
Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6ffhubTa5d6ff"Tb4b4b4: Te6edf3hubTff7b72.Td2a8ffto_dictTb4b4b4(Tb4b4b4)Tb4b4b4}Tb4b4b4)

Tf0883e@routesTff7b72.Td2a8ffpostTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/rrc/servers/Tffd700{hub_id}Ta5d6ff/startTa5d6ff"Tb4b4b4)
Tff7b72async Tff7b72def Td2a8ffrrc_server_startTb4b4b4(Te6edf3requestTb4b4b4)Tb4b4b4:
Te6edf3managerTb4b4b4, Te6edf3hubTb4b4b4, Te6edf3error Tff7b72= Te6edf3_rrc_server_require_hubTb4b4b4(
Te6edf3requestTff7b72.Td2a8ffmatch_infoTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffhub_idTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ff"Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Tff7b72if Te6edf3error Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Tff7b72return Te6edf3error
Te6edf3managerTff7b72.Td2a8ffstart_hubTb4b4b4(Te6edf3hubTff7b72.Td2a8ffhub_idTb4b4b4)
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6ffhubTa5d6ff"Tb4b4b4: Te6edf3hubTff7b72.Td2a8ffto_dictTb4b4b4(Tb4b4b4)Tb4b4b4}Tb4b4b4)

Tf0883e@routesTff7b72.Td2a8ffpostTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/rrc/servers/Tffd700{hub_id}Ta5d6ff/stopTa5d6ff"Tb4b4b4)
Tff7b72async Tff7b72def Td2a8ffrrc_server_stopTb4b4b4(Te6edf3requestTb4b4b4)Tb4b4b4:
Te6edf3managerTb4b4b4, Te6edf3hubTb4b4b4, Te6edf3error Tff7b72= Te6edf3_rrc_server_require_hubTb4b4b4(
Te6edf3requestTff7b72.Td2a8ffmatch_infoTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffhub_idTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ff"Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Tff7b72if Te6edf3error Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Tff7b72return Te6edf3error
Te6edf3managerTff7b72.Td2a8ffstop_hubTb4b4b4(Te6edf3hubTff7b72.Td2a8ffhub_idTb4b4b4)
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6ffhubTa5d6ff"Tb4b4b4: Te6edf3hubTff7b72.Td2a8ffto_dictTb4b4b4(Tb4b4b4)Tb4b4b4}Tb4b4b4)

Tf0883e@routesTff7b72.Td2a8ffpostTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/rrc/servers/Tffd700{hub_id}Ta5d6ff/announceTa5d6ff"Tb4b4b4)
Tff7b72async Tff7b72def Td2a8ffrrc_server_announceTb4b4b4(Te6edf3requestTb4b4b4)Tb4b4b4:
Te6edf3_Tb4b4b4, Te6edf3hubTb4b4b4, Te6edf3error Tff7b72= Te6edf3_rrc_server_require_hubTb4b4b4(
Te6edf3requestTff7b72.Td2a8ffmatch_infoTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffhub_idTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ff"Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Tff7b72if Te6edf3error Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Tff7b72return Te6edf3error
Te6edf3hubTff7b72.Td2a8ffannounce_nowTb4b4b4(Tb4b4b4)
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6ffmessageTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffAnnouncedTa5d6ff"Tb4b4b4}Tb4b4b4)

Tf0883e@routesTff7b72.Td2a8ffpostTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/rrc/servers/Tffd700{hub_id}Ta5d6ff/roomsTa5d6ff"Tb4b4b4)
Tff7b72async Tff7b72def Td2a8ffrrc_server_room_createTb4b4b4(Te6edf3requestTb4b4b4)Tb4b4b4:
Te6edf3managerTb4b4b4, Te6edf3hubTb4b4b4, Te6edf3error Tff7b72= Te6edf3_rrc_server_require_hubTb4b4b4(
Te6edf3requestTff7b72.Td2a8ffmatch_infoTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffhub_idTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ff"Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Tff7b72if Te6edf3error Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Tff7b72return Te6edf3error
Te6edf3data Tff7b72= Tff7b72await Te6edf3requestTff7b72.Td2a8ffjsonTb4b4b4(Tb4b4b4)
Te6edf3name Tff7b72= Tb4b4b4(Te6edf3dataTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffnameTa5d6ff"Tb4b4b4) Tff7b72or Ta5d6ff"Ta5d6ff"Tb4b4b4)Tff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4)
Tff7b72if Tff7b72not Te6edf3nameTb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(
Tb4b4b4{Ta5d6ff"Ta5d6ffmessageTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffA room name is requiredTa5d6ff"Tb4b4b4}Tb4b4b4,
Te6edf3statusTff7b72=T79c0ff400Tb4b4b4,
Tb4b4b4)
Te6edf3topic Tff7b72= Tb4b4b4(Te6edf3dataTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6fftopicTa5d6ff"Tb4b4b4) Tff7b72or Ta5d6ff"Ta5d6ff"Tb4b4b4)Tff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4) Tff7b72or Tff7b72None
Te6edf3private Tff7b72= Tffa657boolTb4b4b4(Te6edf3dataTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffprivateTa5d6ff"Tb4b4b4, Tff7b72FalseTb4b4b4)Tb4b4b4)
Te6edf3moderated Tff7b72= Tffa657boolTb4b4b4(Te6edf3dataTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffmoderatedTa5d6ff"Tb4b4b4, Tff7b72FalseTb4b4b4)Tb4b4b4)
Te6edf3invite_only Tff7b72= Tffa657boolTb4b4b4(Te6edf3dataTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffinvite_onlyTa5d6ff"Tb4b4b4, Tff7b72FalseTb4b4b4)Tb4b4b4)
Te6edf3topic_ops_only Tff7b72= Tffa657boolTb4b4b4(Te6edf3dataTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6fftopic_ops_onlyTa5d6ff"Tb4b4b4, Tff7b72FalseTb4b4b4)Tb4b4b4)
Te6edf3no_outside_msgs Tff7b72= Tffa657boolTb4b4b4(Te6edf3dataTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffno_outside_msgsTa5d6ff"Tb4b4b4, Tff7b72FalseTb4b4b4)Tb4b4b4)
Te6edf3key Tff7b72= Tb4b4b4(Te6edf3dataTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffkeyTa5d6ff"Tb4b4b4) Tff7b72or Ta5d6ff"Ta5d6ff"Tb4b4b4)Tff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4) Tff7b72or Tff7b72None
Tff7b72tryTb4b4b4:
Te6edf3managerTff7b72.Td2a8ffcreate_roomTb4b4b4(
Te6edf3hubTff7b72.Td2a8ffhub_idTb4b4b4,
Te6edf3nameTb4b4b4,
Te6edf3topicTff7b72=Te6edf3topicTb4b4b4,
Te6edf3privateTff7b72=Te6edf3privateTb4b4b4,
Te6edf3moderatedTff7b72=Te6edf3moderatedTb4b4b4,
Te6edf3invite_onlyTff7b72=Te6edf3invite_onlyTb4b4b4,
Te6edf3topic_ops_onlyTff7b72=Te6edf3topic_ops_onlyTb4b4b4,
Te6edf3no_outside_msgsTff7b72=Te6edf3no_outside_msgsTb4b4b4,
Te6edf3keyTff7b72=Te6edf3keyTb4b4b4,
Tb4b4b4)
Tff7b72except Tf85149ValueError Tff7b72as Te6edf3eTb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6ffmessageTa5d6ff"Tb4b4b4: Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4}Tb4b4b4, Te6edf3statusTff7b72=T79c0ff400Tb4b4b4)
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6ffhubTa5d6ff"Tb4b4b4: Te6edf3hubTff7b72.Td2a8ffto_dictTb4b4b4(Tb4b4b4)Tb4b4b4}Tb4b4b4)

Tf0883e@routesTff7b72.Td2a8ffdeleteTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/rrc/servers/Tffd700{hub_id}Ta5d6ff/rooms/Tffd700{room}Ta5d6ff"Tb4b4b4)
Tff7b72async Tff7b72def Td2a8ffrrc_server_room_deleteTb4b4b4(Te6edf3requestTb4b4b4)Tb4b4b4:
Te6edf3managerTb4b4b4, Te6edf3hubTb4b4b4, Te6edf3error Tff7b72= Te6edf3_rrc_server_require_hubTb4b4b4(
Te6edf3requestTff7b72.Td2a8ffmatch_infoTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffhub_idTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ff"Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Tff7b72if Te6edf3error Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Tff7b72return Te6edf3error
Te6edf3managerTff7b72.Td2a8ffdelete_roomTb4b4b4(Te6edf3hubTff7b72.Td2a8ffhub_idTb4b4b4, Te6edf3requestTff7b72.Td2a8ffmatch_infoTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffroomTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ff"Tb4b4b4)Tb4b4b4)
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6ffhubTa5d6ff"Tb4b4b4: Te6edf3hubTff7b72.Td2a8ffto_dictTb4b4b4(Tb4b4b4)Tb4b4b4}Tb4b4b4)

Tf0883e@routesTff7b72.Td2a8ffputTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/rrc/servers/Tffd700{hub_id}Ta5d6ff/rooms/Tffd700{room}Ta5d6ff/keyTa5d6ff"Tb4b4b4)
Tff7b72async Tff7b72def Td2a8ffrrc_server_room_set_keyTb4b4b4(Te6edf3requestTb4b4b4)Tb4b4b4:
Te6edf3managerTb4b4b4, Te6edf3hubTb4b4b4, Te6edf3error Tff7b72= Te6edf3_rrc_server_require_hubTb4b4b4(
Te6edf3requestTff7b72.Td2a8ffmatch_infoTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffhub_idTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ff"Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Tff7b72if Te6edf3error Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Tff7b72return Te6edf3error
Te6edf3room Tff7b72= Te6edf3requestTff7b72.Td2a8ffmatch_infoTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffroomTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ff"Tb4b4b4)
Te6edf3data Tff7b72= Tff7b72await Te6edf3requestTff7b72.Td2a8ffjsonTb4b4b4(Tb4b4b4)
Te6edf3raw_key Tff7b72= Te6edf3dataTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffkeyTa5d6ff"Tb4b4b4)
Tff7b72if Te6edf3raw_key Tff7b72is Tff7b72None Tff7b72or Te6edf3raw_key Tff7b72== Ta5d6ff"Ta5d6ff"Tb4b4b4:
Te6edf3key Tff7b72= Tff7b72None
Tff7b72elif Tffa657isinstanceTb4b4b4(Te6edf3raw_keyTb4b4b4, Tffa657strTb4b4b4)Tb4b4b4:
Te6edf3key Tff7b72= Te6edf3raw_keyTff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4) Tff7b72or Tff7b72None
Tff7b72elseTb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(
Tb4b4b4{Ta5d6ff"Ta5d6ffmessageTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffRoom key must be a string or nullTa5d6ff"Tb4b4b4}Tb4b4b4,
Te6edf3statusTff7b72=T79c0ff400Tb4b4b4,
Tb4b4b4)
Tff7b72tryTb4b4b4:
Te6edf3hubTff7b72.Td2a8ffset_room_keyTb4b4b4(Te6edf3roomTb4b4b4, Te6edf3keyTb4b4b4)
Te6edf3managerTff7b72.Td2a8ffsaveTb4b4b4(Tb4b4b4)
Tff7b72except Tb4b4b4(Tf85149TypeErrorTb4b4b4, Tf85149ValueErrorTb4b4b4) Tff7b72as Te6edf3eTb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6ffmessageTa5d6ff"Tb4b4b4: Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4}Tb4b4b4, Te6edf3statusTff7b72=T79c0ff400Tb4b4b4)
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6ffhubTa5d6ff"Tb4b4b4: Te6edf3hubTff7b72.Td2a8ffto_dictTb4b4b4(Tb4b4b4)Tb4b4b4}Tb4b4b4)

Tf0883e@routesTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/rrc/servers/Tffd700{hub_id}Ta5d6ff/membersTa5d6ff"Tb4b4b4)
Tff7b72async Tff7b72def Td2a8ffrrc_server_membersTb4b4b4(Te6edf3requestTb4b4b4)Tb4b4b4:
Te6edf3_Tb4b4b4, Te6edf3hubTb4b4b4, Te6edf3error Tff7b72= Te6edf3_rrc_server_require_hubTb4b4b4(
Te6edf3requestTff7b72.Td2a8ffmatch_infoTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffhub_idTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ff"Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Tff7b72if Te6edf3error Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Tff7b72return Te6edf3error
Te6edf3room Tff7b72= Te6edf3requestTff7b72.Td2a8ffrel_urlTff7b72.Td2a8ffqueryTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffroomTa5d6ff"Tb4b4b4)
Te6edf3room_arg Tff7b72= Te6edf3roomTff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4) Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3roomTb4b4b4, Tffa657strTb4b4b4) Tff7b72and Te6edf3roomTff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4) Tff7b72else Tff7b72None
Tff7b72tryTb4b4b4:
Te6edf3members Tff7b72= Te6edf3hubTff7b72.Td2a8ffmembers_dictTb4b4b4(Te6edf3room_argTb4b4b4)
Tff7b72except Tf85149ValueError Tff7b72as Te6edf3eTb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6ffmessageTa5d6ff"Tb4b4b4: Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4}Tb4b4b4, Te6edf3statusTff7b72=T79c0ff400Tb4b4b4)
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6ffmembersTa5d6ff"Tb4b4b4: Te6edf3membersTb4b4b4}Tb4b4b4)

Tf0883e@routesTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/rrc/servers/Tffd700{hub_id}Ta5d6ff/activityTa5d6ff"Tb4b4b4)
Tff7b72async Tff7b72def Td2a8ffrrc_server_activityTb4b4b4(Te6edf3requestTb4b4b4)Tb4b4b4:
Te6edf3_Tb4b4b4, Te6edf3hubTb4b4b4, Te6edf3error Tff7b72= Te6edf3_rrc_server_require_hubTb4b4b4(
Te6edf3requestTff7b72.Td2a8ffmatch_infoTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffhub_idTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ff"Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Tff7b72if Te6edf3error Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Tff7b72return Te6edf3error
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Te6edf3hubTff7b72.Td2a8ffrooms_activityTb4b4b4(Tb4b4b4)Tb4b4b4)

Tf0883e@routesTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/rrc/servers/Tffd700{hub_id}Ta5d6ff/messagesTa5d6ff"Tb4b4b4)
Tff7b72async Tff7b72def Td2a8ffrrc_server_messagesTb4b4b4(Te6edf3requestTb4b4b4)Tb4b4b4:
Te6edf3_Tb4b4b4, Te6edf3hubTb4b4b4, Te6edf3error Tff7b72= Te6edf3_rrc_server_require_hubTb4b4b4(
Te6edf3requestTff7b72.Td2a8ffmatch_infoTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffhub_idTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ff"Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Tff7b72if Te6edf3error Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Tff7b72return Te6edf3error
Te6edf3peer Tff7b72= Te6edf3requestTff7b72.Td2a8ffrel_urlTff7b72.Td2a8ffqueryTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffpeerTa5d6ff"Tb4b4b4)
Tff7b72if Tff7b72not Tffa657isinstanceTb4b4b4(Te6edf3peerTb4b4b4, Tffa657strTb4b4b4) Tff7b72or Tff7b72not Te6edf3peerTff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(
Tb4b4b4{Ta5d6ff"Ta5d6ffmessageTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffpeer query parameter is requiredTa5d6ff"Tb4b4b4}Tb4b4b4,
Te6edf3statusTff7b72=T79c0ff400Tb4b4b4,
Tb4b4b4)
Te6edf3room Tff7b72= Te6edf3requestTff7b72.Td2a8ffrel_urlTff7b72.Td2a8ffqueryTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffroomTa5d6ff"Tb4b4b4)
Te6edf3room_arg Tff7b72= Te6edf3roomTff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4) Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3roomTb4b4b4, Tffa657strTb4b4b4) Tff7b72and Te6edf3roomTff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4) Tff7b72else Tff7b72None
Te6edf3limit Tff7b72= Te6edf3requestTff7b72.Td2a8ffrel_urlTff7b72.Td2a8ffqueryTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6fflimitTa5d6ff"Tb4b4b4)
Tff7b72tryTb4b4b4:
Te6edf3messages Tff7b72= Te6edf3hubTff7b72.Td2a8ffmessages_for_peerTb4b4b4(
Te6edf3peerTff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3roomTff7b72=Te6edf3room_argTb4b4b4,
Te6edf3limitTff7b72=Te6edf3limitTb4b4b4,
Tb4b4b4)
Tff7b72except Tf85149ValueError Tff7b72as Te6edf3eTb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6ffmessageTa5d6ff"Tb4b4b4: Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4}Tb4b4b4, Te6edf3statusTff7b72=T79c0ff400Tb4b4b4)
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6ffmessagesTa5d6ff"Tb4b4b4: Te6edf3messagesTb4b4b4}Tb4b4b4)

Tf0883e@routesTff7b72.Td2a8ffpostTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/rrc/servers/Tffd700{hub_id}Ta5d6ff/moderateTa5d6ff"Tb4b4b4)
Tff7b72async Tff7b72def Td2a8ffrrc_server_moderateTb4b4b4(Te6edf3requestTb4b4b4)Tb4b4b4:
Te6edf3_Tb4b4b4, Te6edf3hubTb4b4b4, Te6edf3error Tff7b72= Te6edf3_rrc_server_require_hubTb4b4b4(
Te6edf3requestTff7b72.Td2a8ffmatch_infoTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffhub_idTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ff"Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Tff7b72if Te6edf3error Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Tff7b72return Te6edf3error
Te6edf3data Tff7b72= Tff7b72await Te6edf3requestTff7b72.Td2a8ffjsonTb4b4b4(Tb4b4b4)
Te6edf3action Tff7b72= Tb4b4b4(Te6edf3dataTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffactionTa5d6ff"Tb4b4b4) Tff7b72or Ta5d6ff"Ta5d6ff"Tb4b4b4)Tff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4)Tff7b72.Td2a8fflowerTb4b4b4(Tb4b4b4)
Te6edf3peer Tff7b72= Tb4b4b4(Te6edf3dataTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffpeerTa5d6ff"Tb4b4b4) Tff7b72or Ta5d6ff"Ta5d6ff"Tb4b4b4)Tff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4)
Te6edf3room Tff7b72= Tb4b4b4(Te6edf3dataTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffroomTa5d6ff"Tb4b4b4) Tff7b72or Ta5d6ff"Ta5d6ff"Tb4b4b4)Tff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4) Tff7b72or Tff7b72None
Tff7b72if Te6edf3action Tff7b72not Tff7b72in Tb4b4b4(Ta5d6ff"Ta5d6ffkickTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffbanTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffroom_banTa5d6ff"Tb4b4b4)Tb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(
Tb4b4b4{Ta5d6ff"Ta5d6ffmessageTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffaction must be kick, ban, or room_banTa5d6ff"Tb4b4b4}Tb4b4b4,
Te6edf3statusTff7b72=T79c0ff400Tb4b4b4,
Tb4b4b4)
Tff7b72if Tff7b72not Te6edf3peerTb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(
Tb4b4b4{Ta5d6ff"Ta5d6ffmessageTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffpeer is requiredTa5d6ff"Tb4b4b4}Tb4b4b4,
Te6edf3statusTff7b72=T79c0ff400Tb4b4b4,
Tb4b4b4)
Tff7b72tryTb4b4b4:
Tff7b72if Te6edf3action Tff7b72== Ta5d6ff"Ta5d6ffkickTa5d6ff"Tb4b4b4:
Tff7b72if Tff7b72not Te6edf3roomTb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(
Tb4b4b4{Ta5d6ff"Ta5d6ffmessageTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffroom is required for kickTa5d6ff"Tb4b4b4}Tb4b4b4,
Te6edf3statusTff7b72=T79c0ff400Tb4b4b4,
Tb4b4b4)
Te6edf3hubTff7b72.Td2a8ffadmin_kick_from_roomTb4b4b4(Te6edf3peerTb4b4b4, Te6edf3roomTb4b4b4)
Tff7b72elif Te6edf3action Tff7b72== Ta5d6ff"Ta5d6ffbanTa5d6ff"Tb4b4b4:
Te6edf3hubTff7b72.Td2a8ffadmin_hub_banTb4b4b4(Te6edf3peerTb4b4b4)
Tff7b72elseTb4b4b4:
Tff7b72if Tff7b72not Te6edf3roomTb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(
Tb4b4b4{Ta5d6ff"Ta5d6ffmessageTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffroom is required for room_banTa5d6ff"Tb4b4b4}Tb4b4b4,
Te6edf3statusTff7b72=T79c0ff400Tb4b4b4,
Tb4b4b4)
Te6edf3hubTff7b72.Td2a8ffadmin_room_banTb4b4b4(Te6edf3peerTb4b4b4, Te6edf3roomTb4b4b4)
Tff7b72except Tf85149ValueError Tff7b72as Te6edf3eTb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6ffmessageTa5d6ff"Tb4b4b4: Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4}Tb4b4b4, Te6edf3statusTff7b72=T79c0ff400Tb4b4b4)
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6ffmessageTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffokTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffhubTa5d6ff"Tb4b4b4: Te6edf3hubTff7b72.Td2a8ffto_dictTb4b4b4(Tb4b4b4)Tb4b4b4}Tb4b4b4)

T8b949e# serve telephone status


──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────